#include "mbed.h"
#include "rtos.h"
#include "baidu_mbed_soc_wrapper.h"
#include "baidu_ca_network_socket.h"
#include "baidu_http_client.h"
#if defined(TARGET_UNO_91H)
#include "WiFiStackInterface.h"
#include "SDMMCFileSystem.h"
#elif defined(TARGET_K64F)
#include "SDFileSystem.h"
#else
#error "Not supported"
#endif

#if defined(TARGET_UNO_91H)
static WiFiStackInterface s_net_stack;
// TODO: Configure your AP
#ifndef CUSTOM_SSID
#define CUSTOM_SSID         ("xxx")
#endif // CUSTOM_SSID

#ifndef CUSTOM_PASSWD
#define CUSTOM_PASSWD       ("xxx")
#endif // CUSTOM_PASSWD
#else
static EthernetInterface s_net_stack;
#endif // TARGET_UNO_91H

#ifdef __cplusplus
extern "C" {
#endif
unsigned int OTA_FW_INFO_ADDR = 0x18003000;  //COPY_MODE_FW_INFO_ADDR
unsigned int OTA_UPGRADE_ADDR = 0x18104000;  //COPY_MODE_UPGRADE_ADDR
unsigned int OTA_UPGRADE_AREA_SIZE = 0x100000; //COPY_MODE_FW_MAX_SIZE, must be 4K aligned
#ifdef __cplusplus
}
#endif

#define MDM_CMD_TEST_URL "http://mirrors.sohu.com/ubuntu/ubuntu/ls-lR.gz"

static mbed::Timer s_timer;
static unsigned int s_data_total = 0;
static int s_time_total = 0;
static int s_start_time = 0;

void* baidu_get_netstack_instance(void) {
    return (void*)&s_net_stack;
}

static int data_out_handler(void* /*p_user_ctx*/, e_data_pos pos, const char* buf,
        size_t len, const char* type) {

    printf("download s_data_total = %d\n", s_data_total);
    s_data_total += len;

    if ((pos & DATA_FIRST) == DATA_FIRST) {
        s_start_time = s_timer.read_ms();
    }

    if ((pos & DATA_LAST) == DATA_LAST) {
        s_time_total += s_timer.read_ms() - s_start_time;
    }

    return 0;
}

static void http_speed_test_thread(void const *arg) {
    printf("download thread start\n");
    s_timer.start();

    duer::HttpClient http_client;
    http_client.register_data_handler(data_out_handler, NULL);
    int ret = http_client.get(MDM_CMD_TEST_URL, 0);

    if (ret != 0) {
        printf("download error\n");
    } else {
        float speed = 1.0 * s_data_total * 1000 / s_time_total / 1024;
        printf("download speed is %6.3fKB/S\n", speed);
    }
}

int main() {
    printf("Entry http speed test main!\n");

#if defined(TARGET_UNO_91H)
    if (s_net_stack.connect(CUSTOM_SSID, CUSTOM_PASSWD, NSAPI_SECURITY_NONE) == 0) {
#else
    if (s_net_stack.connect() == 0) {
#endif // TARGET_UNO_91H
        const char* ip = s_net_stack.get_ip_address();
        const char* mac = s_net_stack.get_mac_address();
        printf("IP address is: %s\n", ip ? ip : "No IP");
        printf("MAC address is: %s\n", mac ? mac : "No MAC");
    } else {
        printf("Network initial failed....\n");
        Thread::wait(osWaitForever);
    }

    duer::SocketAdapter::set_network_interface(&s_net_stack);

    Thread mdm_cmd_thread(http_speed_test_thread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE);

    Thread::wait(osWaitForever);
}
